"use strict";
const mvc = require("cosjs.mvc");

module.exports = async function (id, battleData) {
    let ladderBase = this.config("ladderBase");
    let ret = await this.updater.role.model.get(battleData["uid"], ["ladder"]);
    let daily_ladder = await this.updater.daily.model.get('ladder') || [0, 0, 0];
    let selfPlayer = ret[battleData["uid"][0]];
    let targetPlayer = ret[battleData["uid"][1]];
    if (!selfPlayer) {
        return this.error("user not exist", battleData["uid"][0]);
    }
    if (!targetPlayer) {
        return this.error("player not exist", battleData["uid"][1]);
    }
    //总场次
    selfPlayer["ladder"][4] += 1;
    daily_ladder[2] = getValuePlus(daily_ladder[2], 1);
    // this.updater.role.set('ladder',selfPlayer["ladder"][4]);
    //失败
    if (battleData['win'] !== this.updater.uid) {
        selfPlayer["ladder"][2] = 0;
        this.updater.role.set("ladder", selfPlayer["ladder"]);
        this.updater.daily.set('ladder', daily_ladder);
        let _score = scoreFun.call(this, targetPlayer["ladder"][1], selfPlayer["ladder"][1])[1];
        selfPlayer["ladder"][1] = _score;
        selfPlayer["ladder"][0] = this.library('ladder/getDuanwei', selfPlayer["ladder"]);
        //console.log(`积分${_score} => 段位:${selfPlayer["ladder"][0]}`);
        //更新排行榜
        battle_sort.call(this, this.updater.uid, selfPlayer["ladder"][1]);
        return this.updater.save();
    }



    let _redis_result = battleData.tar.split(',');
    for (let i = 1; i < _redis_result.length; ++i) {
        _redis_result[i] = parseInt(_redis_result[i]);
    }
    _redis_result[2] += 1;


    //胜场
    selfPlayer["ladder"][5] += 1;


    //成就 PVP胜利次数
    this.updater.record.add(3800, 1);
    this.updater.record.add(Number(this.config('bpassBase', 'taskKey')), 1)
    //成就 PVP战胜神秘对手次数
    // if(battleData.isMagic){
    //     this.updater.record.add(93139,1);
    // }
    //连胜次数
    selfPlayer["ladder"][2] += 1;
    //每日任务
    daily_ladder[0] = getValuePlus(daily_ladder[0], 1);
    if (battleData.isMagic) {
        daily_ladder[1] = getValuePlus(daily_ladder[1], 1);
    }
    //道具结算
    this.updater.add(ladderBase["battleWinItem"], 1);
    //积分结算
    let score = 0
    //连胜积分
    if (selfPlayer["ladder"][2] > 0) {
        //get max
        let num = Math.min(selfPlayer["ladder"][2], ladderBase['maxStreak']);
        let ladderStreak = this.config("ladderStreak", num);
        if (ladderStreak) {
            score += ladderStreak["score"];
        }
    }
    //自动战斗加成
    if (battleData.isAuto) {
        score += ladderBase['autoExtraScore'];
        this.updater.add(ladderBase['autoExtraKey'], ladderBase['autoExtraVal']);
    }
    //胜利积分
    score += scoreFun.call(this, selfPlayer["ladder"][1], targetPlayer["ladder"][1])[0];
    if (score != selfPlayer["ladder"][1]) {
        selfPlayer["ladder"][1] = score;
        selfPlayer["ladder"][0] = this.library('ladder/getDuanwei', selfPlayer["ladder"]);
        // console.log(`积分${score} => 段位:${selfPlayer["ladder"][0]}`);
        // //计算段位
        // let ladderRank = this.config("ladderRank");
        // for (let k in ladderRank) {
        //     if (selfPlayer["ladder"][1] >= ladderRank[k]["socre"]) {
        //         selfPlayer["ladder"][0] = Math.max(selfPlayer["ladder"][0], ladderRank[k]["id"]);
        //     }
        // } 
    }
    this.updater.role.set("ladder", selfPlayer["ladder"]);
    this.updater.daily.set('ladder', daily_ladder);
    let playerRedis = this.model.redis("ladder/player", this.sid);
    //console.log(`save redis ${battleData["uid"][0]}:${_redis_result[3]}:${_redis_result}`);
    //BOBNOTE 其实可以不等redis的更新结果，直接给用户返回cache？出错的概率有多大？
    await playerRedis.set(battleData["uid"][0], _redis_result[3], _redis_result);

    //更新排行榜
    battle_sort.call(this, this.updater.uid, selfPlayer["ladder"][1]);

    return this.updater.save();
}


//天梯积分结算
function scoreFun(winnerLadder, loserLadder) {
    //结算分数
    let ladderBase = this.config('ladderBase');
    let pl = (winnerLadder - loserLadder) / ladderBase['sumScoreN'];
    let pw = -1 * pl;
    let Ew = 1 / (1 + Math.pow(10, pw));
    let El = 1 / (1 + Math.pow(10, pl));
    winnerLadder += ladderBase['sumScoreK'] * (1 - Ew)
    if (loserLadder > ladderBase['minScore']) {
        loserLadder = Math.max(ladderBase['minScore'], loserLadder + ladderBase['sumScoreK'] * (0 - El))
    }
    // if (loserLadder + ladderBase['sumScoreK'] * (0 - El) >= ladderBase['minScore']) {
    //     loserLadder += ladderBase['sumScoreK'] * (0 - El)
    // } else {
    //     loserLadder = Math.min()
    // }
    // loserLadder = Math.max(loserLadder, ladderBase['minScore'])
    winnerLadder = Math.ceil(winnerLadder)
    loserLadder = Math.floor(loserLadder)
    return [winnerLadder, loserLadder]
}



function battle_sort(uid, ladder) {
    let karr = ['bwinweek']
    let week = this.library("time/week");
    karr.push(this.library("time/sign", week));
    let kstr = karr.join('');

    let redis = this.model.redis("sort", this.sid, kstr);

    redis.stamp();
    // redis.limit(100);
    return redis.set(uid, ladder);
}
module.exports.updateRank = battle_sort;
module.exports.getRank = function (week_offset) {
    // let karr = ['bwinweek']
    // let week = this.library("time/week",week_offset);
    // karr.push(this.library("time/sign", week));
    // let kstr = karr.join('');
    let redis = this.model.redis("sort", this.sid, "PvP_3V3_Sort");
    return redis;
}


function getValuePlus(_arg, _arg1) {
    if (!_arg) {
        return 0 + _arg1;
    }
    if (isNaN(_arg)) {
        return 0 + _arg1;
    }
    return _arg + _arg1;
}


module.exports.getPlayer = async function (is_slient) {
    let rank, order = this.library('ladder/getRank', 0);
    let _ret = await Promise.all([order.get(this.uid), order.size()]);
    let sort = _ret[0];
    let size = _ret[1];
    if (sort < 0) {
        rank = Number.POSITIVE_INFINITY;
        //尚未加入排行榜
        // if(is_slient){
        //    return; 
        // }
        // else{
        //    return this.error("NeedJoin","Msg");
        // }
        rank = 100;
    }
    else {
        rank = sort + 1;
    }



    let ladderPlayer = { 0: { 'player': [0, 5, 10, 15, 20, 30] } };// this.config("ladderPlayer");
    // let ladderPlayerKey = 0;
    // for(let k in ladderPlayer){
    //     let v = ladderPlayer[k];
    //     if(rank >= v["rank"][0] && (!v["rank"][1] ||rank <= v["rank"][1] ) ){
    //         ladderPlayerKey = k;break;
    //     }
    // }
    // if(!ladderPlayerKey){
    //     if(is_slient){
    //         return;
    //     }else{
    //         return this.error("ladderPlayer error",rank);
    //     }
    // }
    let playerData = {};
    let uids = {};
    //uids[this.uid]=1;
    const player_list = ladderPlayer[0]['player'];
    // const player_num=player_list.length/2;



    let query_list = [];
    let max_r = size - sort - 2;
    let min_r = -sort;
    //一次性拉出5个要查询的位置
    //1号位    
    let roll = this.library("random/Roll", Math.max(min_r, player_list[0]), Math.min(max_r, player_list[1])) + sort;
    if ((roll >= 0) && (roll != sort)) {
        query_list.push(roll);
    }
    //2号位,3号位
    let roll1 = this.library("random/Roll", Math.max(min_r, player_list[2]), Math.min(max_r, player_list[3])) + sort;
    let roll2 = this.library("random/Roll", Math.max(min_r, player_list[2]), Math.min(max_r, player_list[3])) + sort;
    if ((query_list.indexOf(roll1) == -1) && (roll1 != sort)) {
        query_list.push(roll1);
    }
    if ((query_list.indexOf(roll2) == -1) && (roll2 != sort)) {
        query_list.push(roll2);
    }

    //4号，5号
    roll1 = this.library("random/Roll", Math.max(min_r, player_list[4]), Math.min(max_r, player_list[5])) + sort;
    roll2 = this.library("random/Roll", Math.max(min_r, player_list[4]), Math.min(max_r, player_list[5])) + sort;
    if ((query_list.indexOf(roll1) == -1) && (roll1 != sort)) {
        query_list.push(roll1);
    }
    if ((query_list.indexOf(roll2) == -1) && (roll2 != sort)) {
        query_list.push(roll2);
    }

    //  console.log('======BobFindMe======');
    //  console.log(`sort:${sort} size:${size} min:${min_r} max:${max_r}`);
    // console.log(query_list);

    //补位
    if (query_list.length < 5) {

        let _b = Math.max(sort - 10, 0);
        let _e = Math.min(sort + 10, size);
        for (let i = _b; i < _e; ++i) {
            if ((i != sort) && (query_list.indexOf(i) == -1)) {
                query_list.push(i);
                if (query_list.length >= 5) {
                    break;
                }
            }
        }
    }
    //排序
    query_list.sort((a, b) => { return a - b; });
    console.log(query_list);

    //生成最终查询列表
    let fque_list = [];
    let _que = { index: 0, b: query_list[0], e: query_list[0] };
    for (let i = 1; i < query_list.length; ++i) {
        if (query_list[i] == _que.e + 1) {
            //续
            _que.e++;
        } else {
            let _old = _que;
            fque_list.push(_que);
            _que = { index: _old.index + (_old.e - _old.b + 1), b: query_list[i], e: query_list[i] };
            //console.log(_que);
        }
    }
    fque_list.push(_que);
    let pro_list = [];

    for (let i = 0; i < fque_list.length; ++i) {
        let _que = fque_list[i];
        pro_list.push(order.range(_que.b, _que.e, "WITHSCORES").then(ret => {
            if (ret && Array.isArray(ret)) {
                let ll = ret.length / 2;
                for (let j = 0; j < ll; ++j) {
                    //if(!uids[ret[j*2]]){
                    // playerData[_que.index+j]=[ret[j*2],Math.floor(ret[j*2+1]),0,_que.index+j];
                    console.log("result:", ret);
                    console.log("testdata index :", _que.index, "j:", j);
                    playerData[_que.index + j] = { 'uid': ret[j * 2], 'score': Math.floor(ret[j * 2 + 1]), 'sort': _que.index + j, flag: 0 };
                    uids[ret[j * 2]] = 1;
                    //                        } 
                }
            }
        }));
    }
    console.log("playerData:", playerData);
    await Promise.all(pro_list);
    let playerRedis = this.model.redis("ladder/player", this.sid);
    //先要删除
    await playerRedis.del(this.uid);
    await playerRedis.set(this.uid, playerData);
    return playerData;
}


module.exports.getDuanwei = function (_record) {
    for (let i = 0; i < 24; ++i) {
        const _cof = this.config('ladderRank', i);
        if (_record[1] < _cof.socre) {
            return i - 1;
        }
        if (_record[4] < _cof.times) {
            return i - 1;
        }
        let _rate = (_record[5] / _record[4]) * 10000;
        if (_rate < _cof.winrate) {
            return i - 1;
        }
    }
    return 24;
}


